home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
vbccsrc.lha
/
vbcc
/
declaration.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-07
|
50KB
|
1,529 lines
/* $VER: vbcc (declaration.c) V0.4 */
#include "vbc.h"
static char FILE_[]=__FILE__;
#define PARAMETER 8
#define OLDSTYLE 16
struct const_list *initialization(struct Typ *,int,int);
int test_assignment(struct Typ *,np);
int return_sc,return_reg,has_return;
#ifdef HAVE_TARGET_ATTRIBUTES
unsigned long return_tattr;
#endif
extern int float_used;
extern void optimize(long,struct Var *);
int settyp(int typnew, int typold)
/* Unterroutine fuer declaration_specifiers(). */
{
static int warned_long_double;
if(DEBUG&2) printf("settyp: new=%d old=%d\n",typnew,typold);
if(typold==LONG&&typnew==FLOAT){ error(203); return(DOUBLE);}
if(typold==LONG&&typnew==DOUBLE){
if(!warned_long_double){error(204);warned_long_double=1;}
return(DOUBLE);
}
if(typold!=0&&typnew!=INT){error(47);return(typnew);}
if(typold==0&&typnew==INT) return(INT);
if(typold==0) return(typnew);
if(typold==SHORT||typold==LONG) return(typold);
error(48);
return(typnew);
}
#define dsc if(storage_class) error(49); if(typ||type_qualifiers) error(50)
#define XSIGNED 16384
struct Typ *declaration_specifiers(void)
/* Erzeugt neuen Typ und gibt Zeiger darauf zurueck, */
/* parst z.B. unsigned int, struct bla etc. */
{
int typ=0,type_qualifiers=0,notdone,storage_class,hard_reg;
char *merk,*imerk,sident[MAXI],sbuff[MAXI];
struct Typ *new=mymalloc(TYPS),*t,*ts;
struct struct_declaration *ssd;
struct struct_list (*sl)[];
size_t slsz;
struct Var *v;
#ifdef HAVE_TARGET_ATTRIBUTES
unsigned long tattr=0;
#endif
storage_class=hard_reg=0;
new->next=0; new->exact=0;
do{
killsp();merk=s;cpbez(buff,0);notdone=0;
if(DEBUG&2) printf("ts: %s\n",buff);
if(!strcmp("struct",buff)) notdone=STRUCT;
if(!strcmp("union",buff)) notdone=UNION;
if(notdone!=0){
killsp();
if(*s!='{'){
cpbez(sident,1);
killsp();
ssd=find_struct(sident,0);
if(ssd&&*s=='{'&&find_struct(sident,nesting)&&ssd->count>0) error(13,sident);
if(!ssd||((*s=='{'||*s==';')&&!find_struct(sident,nesting))){
typ=settyp(notdone,typ);
ssd=mymalloc(sizeof(*ssd));
ssd->count=0;
new->exact=ssd=add_sd(ssd);
add_struct_identifier(sident,ssd);
}else{
new->exact=ssd;
typ=settyp(new->flags=notdone,typ);
}
}else{
*sident=0;
typ=settyp(notdone,typ);
ssd=mymalloc(sizeof(*ssd));
ssd->count=0;
new->exact=ssd=add_sd(ssd);
}
if(*s=='{'){
s++;
killsp();
slsz=SLSIZE;
sl=mymalloc(slsz*sizeof(struct struct_list));
ssd->count=0;
imerk=ident;
ts=declaration_specifiers();
while(*s!='}'&&ts){
ident=sbuff;
t=declarator(clone_typ(ts));
killsp();
if(*s==':'){
/* bitfields werden hier noch ignoriert */
np tree;
if((ts->flags&NQ)!=INT) error(51);
s++;killsp();tree=assignment_expression();
if(type_expression(tree)){
if(tree->flags!=CEXPR) error(52);
if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG) error(52);
}
if(tree) free_expression(tree);
}else{
if(*ident==0) error(53);
}
if(type_uncomplete(t)){
error(14,sbuff);
freetyp(t);
break;
}
if((t->flags&NQ)==FUNKT)
error(15,sbuff);
if(*ident!=0){
int i=ssd->count;
while(--i>=0)
if(!strcmp((*sl)[i].identifier,ident))
error(16,ident);
}
(*sl)[ssd->count].styp=t;
(*sl)[ssd->count].identifier=add_identifier(ident,strlen(ident));
ssd->count++;
if(ssd->count>=slsz-1){
slsz+=SLSIZE;
sl=realloc(sl,slsz*sizeof(struct struct_list));
if(!sl){error(12);raus();}
}
killsp();
if(*s==',') {s++;killsp();continue;}
if(*s!=';') error(54); else s++;
killsp();
if(*s!='}'){
if(ts) freetyp(ts);
ts=declaration_specifiers();killsp();
}
}
if(ts) freetyp(ts);
if(ssd->count==0) error(55);
ident=imerk;
add_sl(ssd,sl);
free(sl);
if(*s!='}') error(56); else s++;
new->flags=notdone|type_qualifiers;
}
notdone=1;
}
if(!strcmp("enum",buff)){
/* enumerations; die Namen werden leider noch ignoriert */
killsp();notdone=1;
if(*s!='{'){cpbez(buff,1);killsp();}
if(*s=='{'){
zlong val; struct Var *v; struct Typ *t;
val=l2zl(0L);
s++;killsp();
while(*s!='}'){
cpbez(sident,1);killsp();
if(*sident==0) {error(56);break;}
t=mymalloc(TYPS);
t->flags=CONST|INT;
t->next=0;
if(find_var(sident,nesting)) error(17,sident);
v=add_var(sident,t,AUTO,0); /* AUTO hier klug? */
if(*s=='='){
s++;killsp();
v->clist=initialization(v->vtyp,0,0);
val=zi2zl(v->clist->val.vint);killsp();
}else{
v->clist=mymalloc(CLS);
v->clist->val.vint=val;
v->clist->next=v->clist->other=0;
v->clist->tree=0;
}
vlong=l2zl(1L);val=zladd(val,vlong);
v->vtyp->flags=CONST|ENUM;
if(*s!='}'&&*s!=',') {error(56);break;}
if(*s==',') s++;
killsp();
if(*s=='}') {s++; break;}
}
}
killsp();
typ=settyp(INT,typ);*buff=0;
}
if(!strcmp("void",buff)) {typ=settyp(VOID,typ);notdone=1;}
if(!strcmp("char",buff)) {typ=settyp(CHAR,typ);notdone=1;}
if(!strcmp("short",buff)) {typ=settyp(SHORT,typ);notdone=1;}
if(!strcmp("int",buff)) {typ=settyp(INT,typ);notdone=1;}
if(!strcmp("long",buff)) {typ=settyp(LONG,typ);notdone=1;}
if(!strcmp("float",buff)) {typ=settyp(FLOAT,typ);notdone=1;}
if(!strcmp("double",buff)) {typ=settyp(DOUBLE,typ);notdone=1;}
if(!strcmp("const",buff)){
if(type_qualifiers&CONST) error(58);
type_qualifiers|=CONST;notdone=1;
}
if(!strcmp("volatile",buff)){
if(type_qualifiers&VOLATILE) error(58);
type_qualifiers|=VOLATILE;notdone=1;
}
if(!strcmp("unsigned",buff)){
if(type_qualifiers&(XSIGNED|UNSIGNED)) error(58);
notdone=1;type_qualifiers|=UNSIGNED;
}
if(!strcmp("signed",buff)){
if(type_qualifiers&(XSIGNED|UNSIGNED)) error(58);
notdone=1;type_qualifiers|=XSIGNED;
}
if(!strcmp("auto",buff)) {dsc;storage_class=AUTO;notdone=1;}
if(!strcmp("register",buff)){dsc;storage_class=REGISTER;notdone=1;}
if(!strcmp("static",buff)) {dsc;storage_class=STATIC;notdone=1;}
if(!strcmp("extern",buff)) {dsc;storage_class=EXTERN;notdone=1;}
if(!strcmp("typedef",buff)) {dsc;storage_class=TYPEDEF;notdone=1;}
if(!(c_flags[7]&USEDFLAG)&&!strcmp("__reg",buff)){
char *d;int f=0;
killsp(); if(*s=='(') s++; else error(151);
killsp(); if(*s=='\"') s++; else error(74);
d=buff;
while(*s&&*s!='\"'){
if(d-buff-2>MAXI){
if(!f){ error(206,MAXI);f=1;}
}else *d++=*s;
s++;
}
*d=0;
if(*s=='\"') s++; else error(74);
killsp(); if(*s==')') s++; else error(59);
for(hard_reg=1;hard_reg<=MAXR;hard_reg++){
if(!strcmp(buff,regnames[hard_reg])) break;
}
if(hard_reg>MAXR){ hard_reg=0;error(220,buff);}
notdone=1;
}
#ifdef HAVE_TARGET_ATTRIBUTES
if(!(c_flags[7]&USEDFLAG)){
int i;
for(i=0;g_attr_name[i];i++){
if(!strcmp(g_attr_name[i],buff)){
if(tattr&(1L<<i)) error(227,buff);
tattr|=(1L<<i);
notdone=1;break;
}
}
}
#endif
if(!notdone&&*buff&&typ==0&&!(type_qualifiers&(XSIGNED|UNSIGNED))){
v=find_var(buff,0);
if(v&&v->storage_class==TYPEDEF){
free(new);
new=clone_typ(v->vtyp);
typ=settyp(new->flags,typ);
notdone=1;